﻿
/*for循环。
表达式和语句。
递增运算符和递减运算符：++和–。
组合赋值运算符。
复合语句（语句块）。
逗号运算符。
关系运算符: >、>=、==、<=、<和!=。
while循环。
typedef工具。
do while循环。
字符输入方法get()。
文件尾条件。
嵌套循环和二维数组。*/
#include "HelloWorld.h"
#include "Chapter5LoopsAndRelationalExpressions.h"
#include <string>
#include <vector>
#include <cstring>
#include <array>
#include <iostream>
#include <ostream>
#include <random>
#include <ctime>
#define Ch5 Chapter5LoopsAndRelationalExpressions

using namespace std;
using Ch5 = Chapter5LoopsAndRelationalExpressions;
//for循环
void Ch5::foreachTest()
{
    int i;
    for (i = 0; i < 5; i++)
    cout<<"C++ Know loops i : "<<i<<'\n';
    cout<<"C++ Know when to stop"<<"\n";
    //cin>>i;
    int limit =5 ;
    //初始化部分：j = limit; 将 j 设置为 5。 并且准许初始化定义变量int i= 1;
    //条件部分：j; 在 C++ 中，非零值被视为真，所以只要 j 不是零，循环就会继续。
    //更新部分：j--; 在每次循环迭代结束时，j 的值会递减 1。
    //推荐,条件部分,使用j>0
    for (int j=limit;j;j--)
        cout<<"j = "<<j<<'\n';
    //声明的方式
    int x ,y ,z;
    x = y = z =0;
    /*cout<<"x = "<<x<<'\n';
    cout<<"y = "<<y<<'\n';
    cout<<"z = "<<z<<'\n';
    cout<<"x>3 = "<<(x>3)<<'\n';
    cout<<"y<3 = "<<(y<3)<<'\n';
    //这行代码的作用是设置标准输出流 cout 的格式标志，使其能够以文本形式输出布尔值 true 和 false，而不是数字 1 和 0。
    cout.setf(ios_base::boolalpha);
    cout<<"x>3 = "<<(x>3)<<'\n';
    cout<<"y<3 = "<<(y<3)<<'\n';*/
    
    //阶乘
    //定义一个数组必须用常量表达式.
    const int airSize= 1;
    long long air[airSize];
    air[0]=1;
    cout<<"0! = "<<air[0]<<'\n';
    for(i=1;i<airSize;i++)
    {
        air[i]=air[i-1]*i;
        //cout<<i<<"! = "<<air[i]<<'\n';
    }
    //步长
   for(i=0;i<100;i+=airSize){
       //cout<<i<<'\n';
   }
    //string输入一个字符串.反向输出
    string str="zyf";
    cin>>str;
    //int len=(int)str.length();
    //for(i=len-1;i>=0;i--)
    //cout<<str[i];

     x= ++x;
     y+=x;
     z=y++;
    // x=++x;
    //奇怪的声明,但是可以编译成功.
    //x=(17,240);
    cout<<z<<'\n';
    cout<<x<<'\n';
    cout<<y<<'\n';

        
}

void Ch5::foreachLoopTest()
{
    //Ch5::foreachTest();可以直接使用.同一类中,会隐性实例化
    //foreachLoopTest() 函数内部调用 foreachTest() 时，实际上发生了以下事情：
    //this->foreachTest();
    //foreachTest();
}

void Ch5::foreachStrcmp()
{
    char chars[5]="?ark";
    cout<<chars<<'\n';
    //strcmp 大于零,小于零,等于零.
    for (char i = 'a'; strcmp(chars, "mark")!=0; i++) {
        
        chars[0] = i;
        cout << chars[0] << '\n';
        cout << chars << '\n';
    }
    cout<<"after loop ends,words is : "<<chars<<'\n';
}

void Ch5::whileTest()
{
    int i=2;
    while(i>1)
    {
       
        cout<<i<<'\n';
        i--;
    }

    string str="Mark";
    i=0;
    // str[i]!= '\0' 也可以str[i],str[i]为空时,其编码将为0,或false 
    while(str[i])
    {   //循环体必须修改i的值
        //cout<<str[i]<<" : "<<int(str[i])<<'\n';
        cout<<str[i]<<" : "<<str[i]<<'\n';
        i++;
    }
    //等待一段时间,没办法控制时间,使用lock_t()
    /*long wait=0;
    while(wait<10000){
        wait++;
    }*/
    
    cout<<"Enter the delay time, in seconds: \n";
    long secs;
    cin>>secs;
    clock_t delay  =secs * CLOCKS_PER_SEC;
    //调用clock()函数，它返回自程序开始执行到当前时刻所经过的时钟计时单元数，并将这个值赋给变量start。
    clock_t start=clock();
    //这意味着从程序开始到调用 clock() 函数，大约经过了 0.003613 秒。这是一个非常短的时间段
    cout <<start<<"starting\a\n";
    while (clock()-start<delay)
        ;
    cout<<"done \a\n";
}

//它是出口循环,首先执行循环体,然后在判断表达式.
void Ch5::doWhileTest()
{
    int n=0;
    cout<<"Enter the number int hte range 1-10 to find : ";
    cout<<"my favorite number\n";
    //循环体
    /*do
    {
        cin>>n;
    }
    //true条件,循环do
    while (n!=7);
    cout<<"yes,7 is my favorite.\n";*/
    
    //奇怪的for循环
    for (;;n++){
            if (n>=2)break;
    }
    
    for (;;)
    {
        n++;
        if (n>=2)break;
    }
    cout<<n<<'\n';
}

//循环范围
void Ch5::rangeForeach()
{
    double prices [5]={1.08,2.9,3.09,4.99,5.1};
    //两种遍历的区别。一个是引用修改无效，一个是地址可以修改值。
    for (double x:prices)
        cout<<x<<'\n';
    for (double &x:prices)
    {
        x=x*.8;//20%off sale
        cout<<x<<'\n';
    }
    for (int x :{3,5,2,8,6})
        cout<<x<<'\n';
}

void Ch5::TextAndForeach()
{
    //判断cin是否结束,使用哨兵字符(sentinel character)将其作为停止的标记
    char ch;
    int count=0;
    cout<<"Enter  character; enter # to quit:\n";
    cin>>ch;
    while (ch!='#')
    {
        count++;
        cout<<ch;
        //版本1.0
        //cin>>ch;
        //改进2.0
        cin.get(ch);//可以包含空格，155页这里介绍了：c语言只能修改地址来改变。和c++不需要（第八章的函数重载）
        //cout<<ch<<'\n';
       
    }
    
    
    cout<<count<<" characters read"<<'\n';
}
//输入一个文件结束符（EOF）。不知道ide的结束符是什么。没成
void Ch5::readingCharsToEnd()
{
    char ch;
    int count=0;
    cout<<"Enter  character; enter # to quit:\n";
    cin.get(ch);
    while (cin.fail()==false)
    {
        cout<<ch;
        count++;
        cin.get(ch);
    }
    cout<<'\n'<<count<<" characters read"<<'\n';
}

void Ch5::rowAndCol()
{

    //二维数组
     int btus[4][5]={
        {1,2,3,4,5},
        {6,7,8,9,10},
        {11,12,13,14,15},
        {16,17,18,19,20},
    };
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<5;j++)
            cout<<btus[i][j]<<'\n';
    }
    //语法糖写法.语法糖是为了统一格式标准,注重代码的开发效率质量.而不是性能
    /*for(int(&row)[5]:btus)
    {
        for(int &x:row)
        cout<<x<<'\n';
    }*/
    //二维数组 不会的地方
    const int Cities =5;
    const int Years =4;

    //声明字符串数组char cities[Cities][25];或者string cities[Cities]
    //这种方式是c风格.ai告诉多用string风格数组声明
    const char * cities[Cities]={
    "北京","上海","广州","深圳","香港"
    };
    
    int maxtemps[Years][Cities] = {
    {96,100,87,101,105},
    {96,98,91,107,104},
    {97,101,93,108,107},
    {98,103,95,109,108},
    };
    cout<<"Maximum temperratures for 2008 -2011"<<'\n';
    for(int city=0;city<Cities;city++)
    {
        //遍历cities[]数组的元素
        cout<<cities[city]<<":\t";
        for (int year=0;year<Years;year++)
            //遍历maxtemps[][]数组的元素
            cout<<maxtemps[year][city]<<"\t";
        cout<<'\n';
    }
    cout<<maxtemps[0][0]<<'\n';
}

void Ch5::finalTest()
{
    //1出口循环do while 和入口循环while和for
    //2
    int i;
    for( i=0;i<5;i++)
        cout<<i;
    cout<<'\n'<<i<<'\n';
    //3.
    /*int j;
    for(j=0;j<11;j+=3)
        cout<<j;
    cout<<'\n'<<j<<'\n';*/
    //4
    int j=0;
    while (++j<9)
        cout<<j++<<'\n';//1357

    //5 打印8直接结束.判断是false 不执行do
    int k=8;
    do cout<<"k = "<<k<<'\n';
    while (k++<5);
    //6 编写  打印1,2,4,8,16,32,64的for循环
    i=1;
    do
    {
        cout<<i<<'\n';
        i= i*2;
    }
    while(i<=64);
   //7 如何在循环体中包括多个条件.:用中括号,规定多条件
   //8
    //int x = (1,024);//c语言中,括号从左右到即返回右边的值024是八进制20
    //int y;y=1,024;
    //cout<<x<<'\n';
    //cout<<y<<'\n';
    //9 cin<<和cin.get();的区别.一个不带空格,一个带空格
      
}

void Ch5::finalCodingTest()
{
    // 1编写一个要求用户输入两个整数的程序。该程序将计算并输出这两个整数之间（包括这两个整数）所有整数的和。这里假设先输入较小的整数。
    // 例如，如果用户输入的是2和9，则程序将指出2~9之间所有整数的和为44。
    int i;
    //int j;
   /* cin>>i>>j;
    int sum=0;
    while (i<=j){
       sum+=i;
        i++;
    }
    cout<<sum<<'\n';*/
    
    //2使用 array 对象（而不是数组）和 long double:(10^4932)而不是 long long （9x10^18）重新编写程序清单5.4，并计算100!的值。
    array<long double,101> array;
    array[0] = 1;
    //size_t 的意思:无符号整形 (unsigned int 32位.unsigned long 64位系统)
    //在解释一个与数组索引和大小相关的场景。
    //想要展示一种更加标准化的、可移植的编程实践。
    for (i = 1; i <=100; ++i) {
        array[i] = array[i - 1] * i;
    }
    cout<<array[100]<<'\n';
    //3编写一个要求用户输入数字的程序。每次输入后，程序都将报告到目前为止，所有输入的累计和。 当用户输入0时，程序结束。
    /*i=0,j=0;
    cin>>i;
    while (i!=0)
    {
        j=j+i;
        cout<<j<<'\n';
        cin>>i;
    }*/
    //4 一个人固定每年10块钱.另外一个人每年增值5%.多少年第二个人超过第一个人
    double a=100,b=100;
    for ( i = 1; b<=a; i++)
    {
        cout<<i<<" 年后 :"<<'\n';
        a+=10;
        b=1.05*b;
        cout<<"a:"<<a;
        cout<<" ,b:"<<b<<'\n';
        
    }
    //5 一个数组,存储月份和销售数量.每个月销售提示,全年销售额
     a=12;
    int sum[]={0,0,0};
    const string year[12]={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
    int cont[12] = {
        11,12,13,14,15,16,17,18,19,20,21,22
    };
    /*for ( i = 1; i <=12; i++)
    {
        cout<<year[i-1]<<" : ";
        cout<<cont[i-1]<<"\n";
        sum[0]+=cont[i-1];
    }
    cout<<"全年销量:"<<sum[0]<<'\n';*/
    //6 使用一个二维数组,计算三年的销量,和总销量
    /*int allbook=0;
    int j ;
     int cont3[3][12] = {
        {11,12,13,14,15,16,17,18,19,20,21,22},
        {11,12,13,14,15,16,17,18,19,20,21,23},
        {11,12,13,14,15,16,17,18,19,20,21,24},
    };
    for (  j = 0; j <3; j++){
        cout<<"第:"<<j+1<<"年\n";
    for ( i = 0; i <12; i++)
        {   
            cout<<year[i]<<" : ";
            cout<<cont3[j][i]<<"\n";
            sum[j]+=cont3[j][i];
           
        }
        allbook+= sum[j];
        cout<<j+1<<",年全年销量:"<<sum[j]<<'\n';
    }
    cout<<j+1<<"年总销量:"<<allbook<<'\n';*/

    //7 你希望有几个车?如果输入2.则car#1:输入车子名字:xxx.输入出产日期:xxx;char#2...最后总结:你的愿望清单: 出产日期,车名 换行
    /*int carsum = 0;
    string car[100][2];
    string carName;
    string carYear;
    cout<<"Enter Your will is Car sum:";
    cin>>carsum;
    for(i=0;carsum-i>0;i++)
    {
        cout<<"Car #"<<i+1<<":\n";
        cout<<"输入车子名字:";
        cin>>carName;
        car[i][0]=carName;
        cout<<"输入车子出产日期:";
        cin>>carYear;
        car[i][1]=carYear;
    }
    if(carsum>0){
        cout<<"你想要的车子清单:"<<'\n';
        for(i=0;carsum-i>0;i++)
        {
          cout<<car[i][0]<<'\t';
          cout<<car[i][1]<<'\n';
        }
     }
    else
    {
        cout<<"你不喜欢开车,没有想要的."<<'\n';
    }*/

    //8用char 数组和循环来读取一个又一个单词,直到用户输入done为止.随后,该程序支出用户输入了多少个单词 不包括done在内
    int wordCount = 0;
    /*const int MAX_WORD_LENGTH = 100; // 假设单词最大长度为100
    char word[MAX_WORD_LENGTH + 1]; // 为单词分配空间，+1是为了空字符
   

    cout << "Enter words (to stop, type the word done):" <<'\n';

    // 读取单词直到用户输入 "done"
    while (cin >> word) {
        //直接使用的方法strcmp,来判断单词
        if (strcmp(word, "done") == 0) {
            break; // 如果输入的是 "done"，则退出循环
        }
        wordCount++; // 增加单词计数
    }

    // 输出用户输入的单词总数
    cout << "You entered a total of " << wordCount << " words." <<'\n';*/
    
    //9 使用string
   /*
   string word1;

    cout << "Enter words (type 'done' to finish):" <<'\n';
    //cin >> word1遇到空格会重复执行
    while (cin >> word1) {
        if (word1 == "done") {
            break; // 退出循环
        }
        //std::cout << "You entered: " << word1 <<'\n';
        wordCount ++;
    }
    cout << "You entered a total of " << wordCount << " words." <<'\n';
    */

    //10 输入一个数字n，输出：前面是n-1 的。。。最后一位是*
    int n;
    cin>>n;
    for (i=0;i<n;i++)
    {
        for (int j=1;j<n+1;j++)
        {
            if (n-j>i)
            cout<<".";
            else
                cout<<"*";
        }
        cout<<'\n';
    }
}
//牛顿公式计算平方公,猜测数值 x = (x+n/x)/2.0;重复迭代,最后两次迭代的x差值接近tolerance
double  Ch5::niudunForSqrt(double n, double tolerance =1e-7)
{
    double x = n; // 初始猜测值
    double last_x;
    do
    {
        last_x=x;
        x = (x+n/x)/2.0;
    }
    //ture执行do.false执行跳过往下.
    while (abs(x-last_x)>tolerance);
    return x;
}
//递归
long double Ch5::diguiForeach(int x)
{
    if (x==1)
    {
        return 1.0L;
    }
    else
    {
        return diguiForeach(x-1)+x;
    }
}


//成员函数之间的调用是在同一个实例上下文中进行的，因此不需要显式创建实例。
//而在 main 方法中调用成员函数时，由于 main 不在类的实例上下文中，你必须创建一个实例来指定要操作的对象。
/*
int main()
{
    //两种方式起别名,次方法2.方法1是#include Ch5  Chapter5LoopsAndRelationalExpressions
    //typedef Chapter5LoopsAndRelationalExpressions ch5;
    //ch5 o;
    Ch5 obj; // 创建 Chapter5LoopsAndRelationalExpressions 类的一个实例
    //obj.foreachTest();
    //obj.foreachStrcmp();
    //obj.whileTest();
    //obj.doWhileTest();
    //obj.rangeForeach();
    //obj.TextAndForeach();
     //randomSports();
    //obj.readingCharsToEnd();
    //obj.rowAndCol();
    //obj.finalTest();
    obj.finalCodingTest();
    //cout<<obj.diguiForeach(10);
    //cout<<obj.niudunForSqrt(2);
    return 1;
}
*/
